package io.bdmc.core.udp;

import io.bdmc.common.utils.ByteUtil;
import io.bdmc.core.msp2000.DataBuild;
import io.bdmc.core.msp2000.DataParse;
import io.bdmc.core.msp2000.model.Msp2000Ter2Platform;
import io.bdmc.core.snmp.GwUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class UdpClientSendData {

    public String sendPollCommand(String ip, int port, String hexString) {

        StringBuilder dataStr = new StringBuilder();

        try {
            // 1，创建udp服务。通过DatagramSocket对象。
            DatagramSocket socket = new DatagramSocket();
            byte[] buf = ByteUtil.hexToBytes(hexString);
            DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName(ip), port);
            // 3，通过socket服务，将已有的数据包发送出去。通过send方法。
            socket.send(dp);
            log.info("Sending ip:" + ip + ",port:" + port + ",hex:" + hexString);

            int length = 0;
            for (int i = 0; i < 50; i++) {
                byte[] buffer = new byte[1024 * 5];
                DatagramPacket rPacket = new DatagramPacket(buffer, buffer.length);
                socket.setSoTimeout(20 * 1000);

                socket.receive(rPacket);
                byte[] data = new byte[rPacket.getLength()];
                System.arraycopy(buffer, 0, data, 0, data.length);
                String receiveHex = ByteUtil.bytesToHex(data);
                dataStr.append(Objects.requireNonNull(receiveHex).toUpperCase());

                if (receiveHex.startsWith("FEFE00")) {
                    int mflag = GwUtil.HexToInt(receiveHex.substring(12, 14));
                    int amout = 0;
                    int no = 0;
                    if (mflag == 0) {
                        break;
                    } else {
                        amout = GwUtil.HexToInt(receiveHex.substring(14, 18));
                        no = GwUtil.HexToInt(receiveHex.substring(18, 22));
                        if (amout == no) {
                            break;
                        }
                    }
                } else if (receiveHex.startsWith("3E00") && receiveHex.length() >= 10) {
                    length = ByteUtil.HexToInt(receiveHex.substring(2, 10));
                } else if (dataStr.toString().startsWith("3E3C") && dataStr.toString().length() > 4) {
                    break;
                }
                if ((length != 0) && (length * 2 + 10 == dataStr.length())) {
                    break;
                }

            }
            //日志太大，截取前100位
            String dataReceive = dataStr.length()>100?dataStr.substring(0,100):dataStr.toString()+".........";
            log.info("received ip:" + ip + ",port:" + port + "data:" + dataReceive);
            // 4，关闭资源。
            socket.close();
            // logger.info(String.format("return data:s%",dataStr.toString()));
            return dataStr.toString();
        } catch (Exception e) {
            log.error("ip:" + ip + ",port:" + port + "data:" + hexString + ",msg:" + e.getMessage());
            // e.printStackTrace();
            return dataStr.toString();
        }
    }

    public String sendTcpData(String ip, int port, String hexString) {
        StringBuilder dataStr = new StringBuilder();
        Socket socket = null;
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress(ip, port), 2000);
            socket.setSoTimeout(20000);
            socket.setReceiveBufferSize(1024*10);

            OutputStream out = socket.getOutputStream();
            out.write(ByteUtil.HexToBytes(hexString));
            InputStream in = socket.getInputStream();
       
            for (int i = 0; i < 100; i++) {
                byte[] receivedData = new byte[1024*10];
                int len = in.read(receivedData);
                byte[] data = new byte[len];
                System.arraycopy(receivedData, 0, data, 0, data.length);
                String receiveHex = ByteUtil.bytesToHex(data);
                dataStr.append(Objects.requireNonNull(receiveHex).toUpperCase());

                //sor文件
                if(dataStr.toString().length()>10&&dataStr.toString().startsWith("3E0000")){
                    int length = ByteUtil.HexToInt(dataStr.substring(6, 10))+4;
                    if(length==dataStr.toString().length()/2){
                         break;
                    }
                }else{
                    //非sor文件应答
                    if(dataStr.toString().length()>4&& dataStr.toString().startsWith("3E")&&dataStr.toString().endsWith("3E")){
                        break;
                    }
                    //sor文件应答
                    if(dataStr.toString().length()>8&& dataStr.toString().startsWith("000")){
                       int length = ByteUtil.HexToInt(dataStr.substring(0, 8))+4;
                       if(length==dataStr.toString().length()/2){
                            break;
                       }
                    }
                }
             

            }
            return dataStr.toString();
        } catch (Exception ex) {
            log.error("ip:" + ip + ",port:" + port + "sendData:" + hexString + "reviceDataLen"+dataStr.length()+",msg:" + ex.getMessage());
            return dataStr.toString();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        }

    }

    public String sendTcpDTSData(String ip, int port, String hexString) {
        StringBuilder dataStr = new StringBuilder();
        Socket socket = null;
        List<byte[]> receives = new ArrayList<byte[]>();
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress(ip, port), 2000);
            socket.setReceiveBufferSize(1024*100);

            OutputStream out = socket.getOutputStream();
            out.write(ByteUtil.HexToBytes(hexString));
            InputStream in = socket.getInputStream();
            socket.setSoTimeout(20000);

            for (int i = 0; i < 100; i++) {
                Thread.sleep(500);
                byte[] receivedData = new byte[1024*100];
                int len = in.read(receivedData);
                if (len <= 0) {
                   break;
                }else{
                    System.out.println(len);
                }
                byte[] data = new byte[len];
                System.arraycopy(receivedData, 0, data, 0, data.length);

                receives.add(data);

            }
            for (byte[] bs : receives) {
                 String receiveHex = ByteUtil.bytesToHex(bs);
                dataStr.append(Objects.requireNonNull(receiveHex).toUpperCase());
            }

            return dataStr.toString();

        } catch (Exception ex) {
           
            for (byte[] bs : receives) {
                String receiveHex = ByteUtil.bytesToHex(bs);
               dataStr.append(Objects.requireNonNull(receiveHex).toUpperCase());
           }
           log.error("ip:" + ip + ",port:" + port + "sendData:" + hexString + "reviceDataLen"+dataStr.length()+",msg:" + ex.getMessage());

            return dataStr.toString();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        }

    }

    public String sendSMSData(String ip, int port, String hexString) {
        StringBuilder dataStr = new StringBuilder();
        Socket socket = null;
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress(ip, port), 2000);
            socket.setReceiveBufferSize(1024);

            OutputStream out = socket.getOutputStream();
            out.write(ByteUtil.HexToBytes(hexString));
            InputStream in = socket.getInputStream();
            socket.setSoTimeout(10000);

            byte[] receivedData = new byte[1024];
            int len = in.read(receivedData);
            if (len <= 0) {
                return dataStr.toString();
            }
            byte[] data = new byte[len];
            System.arraycopy(receivedData, 0, data, 0, data.length);
            String receiveHex = ByteUtil.bytesToHex(data);
            dataStr.append(Objects.requireNonNull(receiveHex).toUpperCase());
            return dataStr.toString();

        } catch (Exception ex) {
            log.error("ip:" + ip + ",port:" + port + "sendData:" + hexString + "reviceDataLen"+dataStr.length()+",msg:" + ex.getMessage());
            return dataStr.toString();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        }
    }

    // 发送轮询指令,得到设备数据
    public String getBodyBySendUdp(String host, int port) {
        // 发送轮询指令
        String pollCmd = DataBuild.buildFF00Msg();
        String parseData = sendPollCommand(host, port, pollCmd);

        // 解析多包数据的粘包
        StringBuilder body = new StringBuilder();
        int index;
        while (true) {
            index = parseData.indexOf("FEFE00");
            if (index < 0) {
                break;
            }
            Msp2000Ter2Platform msg = DataParse.parseAllMsg(ByteUtil.hexToBytes(parseData.substring(index)));
            body.append(msg.getData());
            parseData = parseData.substring(msg.getLen() * 2 + 10);

        }
        return body.toString();
    }

    public String sendDataByUdpOLP(String ip, int port, String hexString) {
        StringBuilder dataStr = new StringBuilder();

        try {
            // 1，创建udp服务。通过DatagramSocket对象。
            DatagramSocket socket = new DatagramSocket();
            byte[] buf = ByteUtil.hexToBytes(hexString);
            DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName(ip), port);
            // 3，通过socket服务，将已有的数据包发送出去。通过send方法。
            socket.send(dp);
            log.info("Sending ip:" + ip + ",port:" + port + ",hex:" + hexString);

            int length = 0;
            for (int i = 0; i < 1; i++) {
                byte[] buffer = new byte[1024];
                DatagramPacket rPacket = new DatagramPacket(buffer, buffer.length);
                socket.setSoTimeout(20 * 1000);

                socket.receive(rPacket);
                byte[] data = new byte[rPacket.getLength()];
                System.arraycopy(buffer, 0, data, 0, data.length);
                String receiveHex = ByteUtil.bytesToHex(data);
                assert receiveHex != null;
                if (receiveHex.startsWith("FEFE") && receiveHex.length()>=6) {
                    length = ByteUtil.HexToInt(receiveHex.substring(4, 6));
                }
                if ((length != 0) && (length +3 == data.length)) {
                    dataStr.append(Objects.requireNonNull(receiveHex).toUpperCase());
                    break;
                }

            }
            //日志太大，截取前100位
            String dataReceive = dataStr.length()>100?dataStr.substring(0,100):dataStr.toString()+".........";
            log.info("received ip:" + ip + ",port:" + port + "data:" + dataReceive);
            // 4，关闭资源。
            socket.close();
            // logger.info(String.format("return data:s%",dataStr.toString()));
            return dataStr.toString();
        } catch (Exception e) {
            log.error("ip:" + ip + ",port:" + port + "data:" + hexString + ",msg:" + e.getMessage());
            // e.printStackTrace();
            return dataStr.toString();
        }
    }






}